home *** CD-ROM | disk | FTP | other *** search
- /*
- * M S G 6 . C
- *
- * Functions -
- * smtpdate Converts RFC822 date string to UNIX long
- * sunday Deleted in conversion to standard timezone
- * routines - ECB 10/88
- * eatwhite Returns first nonwhitespace char in string
- * match
- * tzset Deleted in conversion to standard timezone
- * routines - ECB 10/88
- * makedate Convert UNIX time to string
- *
- *
- * R E V I S I O N H I S T O R Y
- *
- * 07/08/84 HAW Created this module for time stamp processing.
- * Most routines in this module were written
- * by Ron Natelie.
- *
- */
- #include "util.h"
- #include "mmdf.h"
-
- extern long atol();
- extern char *ctime();
-
- /*
- * S M T P _ D A T E
- *
- * Take an RFC822 (more or less) date string cp and convert it to
- * unix time. Allows a variety of illegal formats commonly in use.
- *
- */
-
- #define SPACE ' '
- #define HTAB '\t'
-
- long match();
-
- /*
- * Matchtab structure.
- * Used by match routine.
- */
- struct match_tab {
- char *t_string; /* String to match, NULL for last. */
- long t_val; /* Value to be returned. */
- };
-
- /*
- * Month tab matches month names to number.
- */
- struct match_tab month_tab[] = {
- "jan", 1, "feb", 2, "mar", 3, "apr", 4,
- "may", 5, "jun", 6, "jul", 7, "aug", 8,
- "sep", 9, "oct", 10, "nov", 11, "dec", 12,
- NULL, 0
- };
-
- #define H(x) ( (x)*60L*60L)
- struct match_tab zone_tab[] = {
- "ut", 0, "gmt", 0, "est", H(-5), "edt", H(-4),
- "cst", H(-6), "cdt", H(-5), "mst", H(-7), "mdt", H(-6),
- "pst", H(-8), "pdt", H(-7), "met", H(1), "z", 0,
- "a", H(-1), "b", H(-2), "c", H(-3), "d", H(-4),
- "e", H(-5), "f", H(-6), "g", H(-7), "h", H(-8),
- "i", H(-9), "k", H(-10), "l", H(-11), "m", H(-12),
- "n", H(1), "o", H(2), "p", H(3), "q", H(4),
- "r", H(5), "s", H(6), "t", H(7), "u", H(8),
- "v", H(9), "w", H(10), "x", H(11), "y", H(12),
- NULL, 1
- };
-
- #define isleap(y) (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0)
- #define dysize(A) (isleap(A) ? 366: 365)
-
- static int dmsize[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
- extern char *index();
- extern char *eatwhite();
-
- long
- smtpdate(cp)
- register char *cp;
- {
- struct tm *loctime;
- int day, month, year, hours, minutes, seconds;
- int dayno;
- long tval;
- int i;
- char *dp;
- time_t zone, tloc, time();
-
- /*printf("S entry - date str: %s", cp); */
- cp = eatwhite(cp);
- dp = cp;
-
-
- /*
- * Look for digit, supposed to be day of the month, skipping
- * over day of the week stuff.
- */
- while(1) {
- if(*cp == 0) goto bad_date;
- if(isdigit(*cp)) break;
- cp++;
- }
-
- day = atoi(cp);
- /*printf("S day: %d\n",day); */
- /* Skip digits and white space to get to month. */
-
- while(isdigit(*cp)) cp++;
- while( *cp == SPACE || *cp == HTAB || *cp == '-') cp++;
-
- month = (int)match(month_tab, cp, 3);
- if(month == 0) {
- /* Hack here, look for ctime format. */
- day = atoi(&dp[8]);
- month = (int)match(month_tab, &dp[4], 3);
- if(month == 0) goto bad_date;
- year = atoi(&dp[20]);
- hours = atoi(&dp[11]);
- minutes = atoi(&dp[14]);
- seconds = atoi(&dp[17]);
- zone = -1;
- /*printf("S ctime for: y: %d m: %d d: %d h: %d m: %d s: %d\n",year,month,day,hours,minutes,seconds); */
-
- }
- else {
- /* Skip over to the year */
- while(1) {
- if(*cp == 0) goto bad_date;
- if(isdigit(*cp)) break;
- cp++;
- }
- year = atoi(cp);
-
- while(isdigit(*cp)) cp++;
-
- while(*cp && !isdigit(*cp)) cp++;
-
-
- /* Hours, minutes, seconds */
- hours = atoi(cp);
- if(hours > 60) {
- minutes = hours %100;
- hours = hours/100;
- } else {
- cp = index(cp, ':');
- if(cp == NULL) goto bad_date;
- minutes = atoi(++cp);
- }
-
- dp = index(cp, ':');
- if(dp) {
- seconds = atoi(++dp);
- cp = dp;
- }
- else seconds = 0;
- /*printf("S hours: %d mins: %d secs: %d\n",hours,minutes,seconds); */
- while(isdigit(*cp)) cp++;
- cp = eatwhite(cp);
- /*printf("S Zone starts- str: %s",cp); */
- if( (*cp == '+' || *cp == '-') &&
- isdigit(cp[1]) &&
- isdigit(cp[2]) &&
- isdigit(cp[3]) &&
- isdigit(cp[4])
- ) {
- zone = (time_t)(atol(cp+3) * 60L);
- cp[3] = 0;
- zone *= (time_t)atol(cp);
- } else {
- if( *cp == '+' || *cp == '-' )
- cp++;
- dp = cp;
- while(isalpha(*cp)) cp++;
- *cp = 0;
- zone = (time_t)(-match(zone_tab, dp, 0));
- }
- /*printf("S zone: %d\n",zone); */
- }
- if(year < 1900) year += 1900;
- if(month < 1 || month > 12) goto bad_date;
- if(day < 1 || day > 31) goto bad_date;
- if(hours == 24) {
- hours = 0;
- day++;
- }
- if(hours < 0 || hours > 23) goto bad_date;
- if(minutes < 0 || minutes > 59) goto bad_date;
- if(seconds < 0 || seconds > 59) goto bad_date;
-
- tval = 0;
- dayno = 0;
- for(i = 1970; i < year; i++)
- tval += dysize(i);
-
- if(isleap(year) && month >= 3)
- dayno += 1;
- while(--month) dayno += dmsize[month-1];
- tval += dayno;
- tval += day-1;
- tval *= 24;
- tval += hours;
- tval *= 60;
- tval += minutes;
- tval *= 60;
- tval += seconds;
- if(zone == -1) {
- /*
- * Determine our offset from GMT by taking the difference
- * of localtime() and gmtime().
- *
- * Note: zone is now computed in hours and then converted
- * to seconds.
- */
- (void) time(&tloc);
- loctime = localtime(&tloc);
- zone = loctime->tm_hour;
- if (loctime->tm_isdst) {
- /*printf("S changing zone for daylight\n"); */
- zone -= 1L;
- }
- zone = (gmtime(&tloc)->tm_hour - zone) * 3600L;
- /*printf("S timezone: %d dayno: %d\n",zone,dayno); */
- }
- /*printf("S before zone: %s",ctime(&tval)); */
- tval += zone;
- /*printf("S after zone: %s\n",ctime(&tval)); */
- return tval;
-
- bad_date:
- return -1L;
- }
-
- /*
- * E A T W H I T E
- *
- * An old favorite, returns the first non whitespace in the string.
- */
- char *
- eatwhite(cp)
- register char *cp;
- {
- while(*cp == SPACE || *cp == HTAB) cp++;
- return cp;
- }
-
- long
- match(tab, string, size)
- register struct match_tab *tab;
- char *string;
- int size;
- {
- register char *cp, *str;
- char *bufend;
- char buffer[512];
-
- bufend = &buffer[ (size == 0) ? 512 : size];
- for(cp = buffer, str = string; cp < bufend; cp++, str++) {
- if(isupper(*str)) *cp = tolower(*str);
- else *cp = *str;
- if(*cp == 0) break;
- }
-
- while(tab->t_string != NULL) {
- if(size) {
- if(strncmp(buffer,tab->t_string, size) == 0)
- break;
- } else {
- if(strcmp(buffer, tab->t_string) == 0)
- break;
- }
- tab++;
- }
- return tab->t_val;
- }
-
- /*
- * M A K E D A T E
- *
- * Convert UNIX date to string (DD MMM YY)
- */
- makedate( date, dest )
- long *date;
- char *dest;
- {
- char *cp;
-
- cp = ctime( date );
- *dest++ = cp[8];
- *dest++ = cp[9];
- *dest++ = ' ';
- *dest++ = cp[4];
- *dest++ = cp[5];
- *dest++ = cp[6];
- *dest++ = ' ';
- *dest++ = cp[22];
- *dest++ = cp[23];
-
- }
-